package org.ftc.web;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang3.StringUtils;
import org.ftc.domain.Motion;
import org.ftc.domain.Session;
import org.ftc.form.MotionForm;
import org.ftc.service.CodeResolutionService;
import org.ftc.service.CodeTypeService;
import org.ftc.service.CodeUnitService;
import org.ftc.service.FtcLogService;
import org.ftc.service.FtcLogService.Log;
import org.ftc.service.MotionService;
import org.ftc.service.SessionService;
import org.ftc.service.UsersService;
import org.ftc.util.Global;
import org.ftc.util.ListCalculator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MotionController {
	@Autowired
	CodeTypeService codeTypeService;
	@Autowired
	CodeUnitService codeUnitService;
	@Autowired
	CodeResolutionService codeResolutionService;
	@Autowired
	UsersService usersService;
	@Autowired
	MotionService motionService;
	@Autowired
	SessionService sessionService;
	@Autowired
	FtcLogService logService;

	@RequestMapping(value = "/motion.htm")
	public String index(ModelMap model) {
		MotionForm mForm = new MotionForm();
		model.addAttribute("unitSource", codeUnitService.findAll());
		model.addAttribute("searchForm", mForm);//
		return "motion/list";
	}

	@RequestMapping(value = "/motion/list.json", method = RequestMethod.POST)
	public @ResponseBody Map<String, Object> list(MotionForm form, BindingResult binding, ModelMap model) {
		logService.before();
		Map<String, Object> map = new HashMap<String, Object>();
		ListCalculator listCal = new ListCalculator(); 
		int pageSize = form.getRows();
		listCal.setRecordsPerPage( pageSize );
		Integer totalRecs = (int)motionService.count(form);
		int totalPages = listCal.totalPages(totalRecs);  
		int pageNo = form.getPage();
		pageNo = (pageNo >= totalPages) ? totalPages : pageNo;
		int firstRes = listCal.firstResult(pageNo);  
		map.put("total", totalRecs.toString() ); 
		List<Motion> datas = motionService.findPage(form,firstRes, pageSize);
		map.put("rows", datas);
		logService.save(Log.QUERY, this.getClass().toString());
		return map;
	}

	// ========================================================================
	// ==== 基本資料
	// ========================================================================

	@RequestMapping(value = "/motion/get/{sessionNo}.htm")
	public String get(@PathVariable String sessionNo, ModelMap model) {
		logService.before();
		List<Motion> list = motionService.getBySessionNo(sessionNo);
		MotionForm mForm = new MotionForm();
		mForm.setMotions(list);
		model.addAttribute("motionForm", mForm);
		Session session = sessionService.get(sessionNo);
		Motion motion = new Motion();
		motion.setSession(session);
		model.addAttribute("newMotion", motion);
		logService.save(Log.QUERY, this.getClass().toString());
		return "motion/update";
	}

	@RequestMapping(value = "/motion/update.json", method = RequestMethod.POST)
	public @ResponseBody String update(Motion entity, BindingResult binding, ModelMap model) {
		logService.before();
		boolean result = false;
		if (StringUtils.isBlank(entity.getMotionSeq())) {
			Session session = sessionService.get(entity.getSessionNo());
			entity.setSession(session);
			String tempNo = StringUtils.equals(entity.getTypeNo(), "9") //
			? StringUtils.leftPad(entity.getMotionOrder(), 2, "x") //
					: StringUtils.leftPad(entity.getMotionOrder(), 2, "0");
			String tempNo2 = entity.getSessionNo() + entity.getTypeNo() + tempNo;
			entity.setMotionNo(tempNo2);
			result = motionService.save(entity);
			logService.save(Log.INSERT, entity.getMotionNo(), this.getClass().toString(),
					ToStringBuilder.reflectionToString(entity));
			return result ? entity.getMotionSeq() : result + "";
		} else {
			Motion motion = motionService.get(entity.getMotionSeq());
			this.transferMotion(entity, motion);
			result = motionService.update(motion);
			logService.save(Log.UPDATE, entity.getMotionNo(), this.getClass().toString(),
					ToStringBuilder.reflectionToString(entity));
			return result ? "update" : result + "";
		}

	}

	@RequestMapping(value = "/motion/delete/{motionSeq}.json")
	public @ResponseBody boolean delete(@PathVariable String motionSeq) {
		logService.before();
		logService.save(Log.DELETE, motionSeq, this.getClass().toString());
		return motionService.delete(motionSeq);
	}

	private void transferMotion(Motion source, Motion target) {

		String tempNo = StringUtils.equals(source.getTypeNo(), "9") //
		? StringUtils.leftPad(source.getMotionOrder(), 2, "x") //
				: StringUtils.leftPad(source.getMotionOrder(), 2, "0");
		String tempNo2 = source.getSessionNo() + source.getTypeNo() + tempNo;
		target.setMotionNo(tempNo2);
		target.setTypeNo(source.getTypeNo()); // 案別
		target.setType(source.getType()); // 案別名
		target.setMotionOrder(source.getMotionOrder()); // 案次
		target.setProvisional(source.isProvisional()); // 臨時
		target.setIsLegal(source.getIsLegal()); // 是否違法
		target.setDate1(source.getDate1()); // 收文日期
		target.setDate2(source.getDate2()); // 到議事科日期
		target.setUnitCode(source.getUnitCode()); // 提案單位代號
		target.setUnitName(source.getUnitName()); // 提案單位
		target.setTelNo(source.getTelNo()); // 分號
		target.setInCharge(source.getInCharge()); // 承辦
		target.setSectionChief(source.getSectionChief()); // 科長
		target.setUnitCode1(source.getUnitCode1()); // 原提案單位1代號
		target.setUnitName1(source.getUnitName1()); // 原提案單位1
		target.setTelNo1(source.getTelNo1()); // 原分號1
		target.setInCharge1(source.getInCharge1()); // 原承辦1
		target.setSectionChief1(source.getSectionChief1()); // 原科長1
		target.setUnitCode2(source.getUnitCode2()); // 原提案單位2代號
		target.setUnitName2(source.getUnitName2()); // 原提案單位2
		target.setTelNo2(source.getTelNo2()); // 原分號2
		target.setInCharge2(source.getInCharge2()); // 原承辦2
		target.setSectionChief2(source.getSectionChief2()); // 原科長2
		target.setCause(source.getCause()); // 案由
		target.setExaminant(source.getExaminant()); // 案查委員
	}

	// ========================================================================
	// ==== 基本資料
	// ========================================================================
	// ==== 案次決定
	// ========================================================================

	@RequestMapping(value = "/motion/choose/{sessionNo}.htm")
	public String choose(@PathVariable String sessionNo, ModelMap model) {
		MotionForm mForm = new MotionForm();
		mForm.setSessionNo(sessionNo);
		model.addAttribute("searchForm", mForm);//
		return "motion/choose";
	}

	@RequestMapping(value = "/motion/chooseList.json", method = RequestMethod.POST)
	public @ResponseBody Map<String, Object> choose(MotionForm form, BindingResult binding, ModelMap model) {
		logService.before();
		Map<String, Object> json = new HashMap<String, Object>();
		List<Motion> list = motionService.getBySessionNo(form.getSessionNo());
		json.put("rows", list);
		logService.save(Log.QUERY, this.getClass().toString());
		return json;
	}

	@RequestMapping(value = "/motion/updateOrder.json", method = RequestMethod.POST)
	public @ResponseBody boolean updateOrder(Motion entity, BindingResult binding, ModelMap model) {
		logService.before();
		boolean result = false;
		Session session = sessionService.get(entity.getSessionNo());
		Motion motion = motionService.get(entity.getMotionSeq());
		motion.setSession(session);
		motion.setMotionOrder(entity.getMotionOrder());
		String tempNo = StringUtils.equals(entity.getTypeNo(), "9") //
		? StringUtils.leftPad(entity.getMotionOrder(), 2, "x") //
				: StringUtils.leftPad(entity.getMotionOrder(), 2, "0");
		String tempNo2 = entity.getSessionNo() + entity.getTypeNo() + tempNo;
		motion.setMotionNo(tempNo2);
		try {
			result = motionService.update(motion);
		} catch (Exception e) {
			e.printStackTrace();
			return result;
		}
		logService.save(Log.UPDATE, entity.getMotionNo(), this.getClass().toString(),
				ToStringBuilder.reflectionToString(entity));
		return result;

	}

	@RequestMapping(value = "/motion/exclude/{motionSeq}.json")
	public @ResponseBody String exclude(@PathVariable String motionSeq) {
		logService.before();
		boolean result = false;
		Motion motion = motionService.get(motionSeq);
		Session session = motion.getSession();
		Session newSession = sessionService.findNext(session);
		if (newSession != null) { // 下一會期資料
			motion.setSession(newSession);
			String tempNo = StringUtils.equals(motion.getTypeNo(), "9") //
			? StringUtils.leftPad(motion.getMotionOrder(), 2, "x") //
					: StringUtils.leftPad(motion.getMotionOrder(), 2, "0");
			String tempNo2 = motion.getSessionNo() + motion.getTypeNo() + tempNo;
			motion.setMotionNo(tempNo2);
			result = motionService.update(motion);
		}
		logService.save(Log.UPDATE, motionSeq, this.getClass().toString());
		return result + "";
	}

	// ========================================================================
	// ==== 案次決定
	// ========================================================================
	// ==== 決議內容
	// ========================================================================

	@RequestMapping(value = "/motion/decide/{sessionNo}.htm")
	public String decide(@PathVariable String sessionNo, ModelMap model) {
		logService.before();
		List<Motion> list = motionService.getBySessionNo(sessionNo);
		MotionForm mForm = new MotionForm();
		mForm.setMotions(list);
		model.addAttribute("motionForm", mForm);
		model.addAttribute("codeResolution", codeResolutionService.findAll());
		logService.save(Log.QUERY, this.getClass().toString());
		return "motion/decide";
	}

	@RequestMapping(value = "/motion/decide.json", method = RequestMethod.POST)
	public @ResponseBody boolean decide(Motion entity, BindingResult binding, ModelMap model) {
		logService.before();
		boolean result = false;
		Motion motion = motionService.get(entity.getMotionSeq());
		motion.setResolution(entity.getResolution());
		motion.setSubResolution(entity.getSubResolution());
		result = motionService.update(motion);
		logService.save(Log.UPDATE, entity.getMotionNo(), this.getClass().toString(),
				ToStringBuilder.reflectionToString(entity));
		return result;

	}

	@InitBinder
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(Global.APP.DATE_FORMAT);
		dateFormat.setLenient(false);
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
	}
}
